/*
Creates a group if items that can be navigated through using arrow keys or the tab key
*/

const keyboardNavigationHelper = {
  groups: {}, // name: [containers]
  moveFocus: function (group, direction) {
    // 1: forward, -1: backward
    var items = [];
    var realFocusItem;
    var fakeFocusItem;
    keyboardNavigationHelper.groups[group].forEach(function (container) {
      items = items.concat(
        Array.from(
          container.querySelectorAll(
            'input:not(.ignores-keyboard-focus), [tabindex="-1"]:not(.ignores-keyboard-focus)'
          )
        )
      );
      if (!realFocusItem) {
        realFocusItem = container.querySelector(':focus');
      }
      if (!fakeFocusItem) {
        fakeFocusItem = container.querySelector('.fakefocus');
      }
    });

    var currentItem = fakeFocusItem || realFocusItem;

    if (!items) {
      return;
    }
    if (!currentItem) {
      items[0].focus();
      return;
    }

    currentItem.classList.remove('fakefocus');

    while (items.length > 1) {
      var index = items.indexOf(currentItem);

      var nextItem;
      if (items[index + direction]) {
        nextItem = index + direction;
      } else if (index === 0 && direction === -1) {
        nextItem = items.length - 1;
      } else if (index === items.length - 1 && direction === 1) {
        nextItem = 0;
      }
      items[nextItem].focus();

      if (document.activeElement !== items[nextItem]) {
        // this item isn't focusable, try again
        items.splice(nextItem, 1);
      } else {
        // done
        break;
      }
    }
  },
  handleKeypress: function (group, e) {
    if (e.keyCode === 9 && e.shiftKey) {
      // shift+tab
      e.preventDefault();
      keyboardNavigationHelper.moveFocus(group, -1);
    } else if (e.keyCode === 9 || e.keyCode === 40) {
      // tab or arrowdown key
      e.preventDefault();
      keyboardNavigationHelper.moveFocus(group, 1);
    } else if (e.keyCode === 38) {
      // arrowup key
      e.preventDefault();
      keyboardNavigationHelper.moveFocus(group, -1);
    }
  },
  addToGroup: function (group, container) {
    if (!keyboardNavigationHelper.groups[group]) {
      keyboardNavigationHelper.groups[group] = [];
    }

    // insert the containers so that they are ordered based on DOM position
    var pos = 0;
    // compareDocumentPosition is a bit of an unusual API
    while (
      pos <= keyboardNavigationHelper.groups[group].length - 1 &&
      keyboardNavigationHelper.groups[group][pos].compareDocumentPosition(
        container
      ) & Node.DOCUMENT_POSITION_FOLLOWING
    ) {
      pos++;
    }
    keyboardNavigationHelper.groups[group].splice(pos, 0, container);

    container.addEventListener('keydown', function (e) {
      keyboardNavigationHelper.handleKeypress(group, e);
    });
  },
};

export default keyboardNavigationHelper;
